home *** CD-ROM | disk | FTP | other *** search
/ Atari Mega Archive 1 / Atari Mega Archive - Volume 1.iso / language / iconv8_s.arc / ICONT.ARC / TSYM.C < prev    next >
C/C++ Source or Header  |  1990-03-28  |  14KB  |  546 lines

  1. /*
  2.  * tsym.c -- functions for symbol table management.
  3.  */
  4.  
  5. #include "..\h\config.h"
  6. #include "general.h"
  7. #include "tproto.h"
  8. #include "globals.h"
  9. #include "trans.h"
  10. #include "token.h"
  11. #include "tsym.h"
  12.  
  13. #ifndef VarTran
  14. #include "lfile.h"
  15. #endif                    /* VarTran */
  16.  
  17. /*
  18.  * Prototypes.
  19.  */
  20.  
  21. hidden struct    tgentry *alcglob
  22.    Params((struct tgentry *blink, char *name,int flag,int nargs));
  23. hidden struct    tientry *alcid        Params((char *nam,int len));
  24. hidden struct    tcentry *alclit    
  25.    Params((struct tcentry *blink, char *name, int len,int flag));
  26. hidden struct    tlentry *alcloc    
  27.    Params((struct tlentry *blink, char *name,int flag));
  28. hidden struct    tcentry *clookup    Params((char *id,int flag));
  29. hidden struct    tgentry *glookup    Params((char *id));
  30. hidden struct    tlentry *llookup    Params((char *id));
  31. hidden novalue    putglob
  32.    Params((char *id,int id_type, int n_args));
  33. hidden int    streq            Params((int len,char *s1,char *s2));
  34.  
  35. #ifdef DeBugTrans
  36. novalue    cdump    Params((noargs));
  37. novalue    gdump    Params((noargs));
  38. novalue    ldump    Params((noargs));
  39. #endif                    /* DeBugTrans */
  40.  
  41.  
  42. /*
  43.  * putid - install the identifier named by the string starting at strf
  44.  *  and extending for len bytes.  The installation entails making an
  45.  *  entry in the identifier hash table and then making an identifier
  46.  *  table entry for it with alcid.  A side effect of installation
  47.  *  is the incrementing of strf by the length of the string, thus
  48.  *  "saving" it.
  49.  *
  50.  * Nothing is changed if the identifier has already been installed.
  51.  */
  52. char *putid(len)
  53. int len;
  54.    {
  55.    register int hash;
  56.    register char *s;
  57.    register struct tientry *ip;
  58.    int l;
  59.  
  60.    /*
  61.     * Compute hash value by adding bytes and masking result with imask.
  62.     *  (Recall that imask is ihsize-1.)
  63.     */
  64.    s = strf;
  65.    hash = 0;
  66.    l = len;
  67.    while (l--)
  68.       hash += *s++ & 0377;
  69.    s = strf;
  70.    l = len;
  71.    hash &= imask;
  72.    /*
  73.     * If the identifier hasn't been installed, install it.
  74.     */
  75.    if ((ip = ihash[hash]) != NULL) {    /* collision */
  76.       for (;;) {    /* work down i_blink chain until id is found or the
  77.                             end of the chain is reached */
  78.          if (l == ip->i_length && streq(l, s, ip->i_name))
  79.             return (ip->i_name);    /* id is already installed */
  80.          if (ip->i_blink == NULL) {    /* end of chain */
  81.             ip->i_blink = alcid(s,l);
  82.             strf += l;
  83.             return s;
  84.             }
  85.          ip = ip->i_blink;
  86.          }
  87.       }
  88.    /*
  89.     * Hashed to an empty slot.
  90.     */
  91.    ihash[hash] = alcid(s,l);
  92.    strf += l;
  93.    return s;
  94.    }
  95.  
  96. /*
  97.  * streq - compare s1 with s2 for len bytes, and return 1 for equal,
  98.  *  0 for not equal.
  99.  */
  100. static int streq(len, s1, s2)
  101. register int len;
  102. register char *s1, *s2;
  103.    {
  104.    while (len--)
  105.       if (*s1++ != *s2++)
  106.          return 0;
  107.    return 1;
  108.    }
  109.  
  110. /*
  111.  * alcid - get the next free identifier table entry, and fill it in with
  112.  *  the specified values.
  113.  */
  114. static struct tientry *alcid(nam, len)
  115. char *nam;
  116. int len;
  117.    {
  118.    register struct tientry *ip;
  119.  
  120.    if (ifree >= &itable[isize])
  121.       tsyserr("out of identifier table space");
  122.    ip = ifree++;
  123.    ip->i_blink = NULL;
  124.    ip->i_name = nam;
  125.    ip->i_length = len;
  126.    return ip;
  127.    }
  128.  
  129. #ifndef VarTran
  130.  
  131. /*
  132.  * loc_init - clear the local symbol table.
  133.  */
  134.  
  135. novalue loc_init()
  136.    {
  137.    register struct tlentry **lp;
  138.    register struct tcentry **cp;
  139.    static int maxlfree = 0;
  140.    static int maxcfree = 0;
  141.                     /* clear local table */
  142.    maxlfree = (maxlfree > lfree-ltable) ? maxlfree : lfree-ltable;
  143.    for (lp = lhash; lp < &lhash[lhsize]; lp++)
  144.       *lp = NULL;
  145.    lfree = ltable;
  146.                     /* clear constant table */
  147.    maxcfree = (maxcfree > ctfree-ctable) ? maxcfree : ctfree-ctable;
  148.    for (cp = chash; cp < &chash[chsize]; cp++)
  149.       *cp = NULL;
  150.    ctfree = ctable;
  151.    }
  152.  
  153. /*
  154.  * install - put an identifier into the global or local symbol table.
  155.  *  The basic idea here is to look in the right table and install
  156.  *  the identifier if it isn't already there.  Some semantic checks
  157.  *  are performed.
  158.  */
  159. novalue install(name, flag, argcnt)
  160. char *name;
  161. int flag, argcnt;
  162.    {
  163.    union {
  164.       struct tgentry *gp;
  165.       struct tlentry *lp;
  166.       } p;
  167.  
  168.    switch (flag) {
  169.       case F_Global:    /* a variable in a global declaration */
  170.          if ((p.gp = glookup(name)) == NULL)
  171.             putglob(name, flag, argcnt);
  172.          else
  173.             p.gp->g_flag |= flag;
  174.          break;
  175.  
  176.       case F_Proc|F_Global:    /* procedure declaration */
  177.       case F_Record|F_Global:    /* record declaration */
  178.       case F_Builtin|F_Global:    /* external declaration */
  179.          if ((p.gp = glookup(name)) == NULL)
  180.             putglob(name, flag, argcnt);
  181.          else if ((p.gp->g_flag & (~F_Global)) == 0) { /* superfluous global
  182.                                declaration for
  183.                                record or proc */
  184.             p.gp->g_flag |= flag;
  185.             p.gp->g_nargs = argcnt;
  186.             }
  187.          else            /* the user can't make up his mind */
  188.             tfatal("inconsistent redeclaration", name);
  189.          break;
  190.  
  191.       case F_Static:    /* static declaration */
  192.       case F_Dynamic:    /* local declaration (possibly implicit?) */
  193.       case F_Argument:    /* formal parameter */
  194.          if ((p.lp = llookup(name)) == NULL)
  195.             putloc(name,flag);
  196.          else if (p.lp->l_flag == flag) /* previously declared as same type */
  197.             tfatal("redeclared identifier", name);
  198.          else        /* previously declared as different type */
  199.             tfatal("inconsistent redeclaration", name);
  200.          break;
  201.  
  202.       default:
  203.          tsyserr("install: unrecognized symbol table flag.");
  204.       }
  205.    }
  206.  
  207. /*
  208.  * putloc - make a local symbol table entry and return the index
  209.  *  of the entry in lhash.  alcloc does the work if there is a collision.
  210.  */
  211. int putloc(id,id_type)
  212. char *id;
  213. int id_type;
  214.    {
  215.    register struct tlentry *ptr;
  216.  
  217.    if ((ptr = llookup(id)) == NULL) {    /* add to head of hash chain */
  218.       ptr = lhash[lhasher(id)];
  219.       lhash[lhasher(id)] = alcloc(ptr, id, id_type);
  220.       return (lhash[lhasher(id)] - ltable);
  221.       }
  222.    return (ptr - ltable);
  223.    }
  224.  
  225. /*
  226.  * putglob makes a global symbol table entry. alcglob does the work if there
  227.  *  is a collision.
  228.  */
  229.  
  230. static novalue putglob(id, id_type, n_args)
  231. char *id;
  232. int id_type, n_args;
  233.    {
  234.    register struct tgentry *ptr;
  235.  
  236.    if ((ptr = glookup(id)) == NULL) {     /* add to head of hash chain */
  237.       ptr = ghash[ghasher(id)];
  238.       ghash[ghasher(id)] = alcglob(ptr, id, id_type, n_args);
  239.       }
  240.    }
  241.  
  242. /*
  243.  * putlit makes a constant symbol table entry and returns the index
  244.  *  of the entry in chash.  alclit does the work if there is a collision.
  245.  */
  246. int putlit(id, idtype, len)
  247. char *id;
  248. int len, idtype;
  249.    {
  250.    register struct tcentry *ptr;
  251.  
  252.    if ((ptr = clookup(id,idtype)) == NULL) {   /* add to head of hash chain */
  253.       ptr = chash[chasher(id)];
  254.       chash[chasher(id)] = alclit(ptr, id, len, idtype);
  255.       return (chash[chasher(id)] - ctable);
  256.       }
  257.    return (ptr - ctable);
  258.    }
  259.  
  260. /*
  261.  * llookup looks up id in local symbol table and returns pointer to
  262.  *  to it if found or NULL if not present.
  263.  */
  264.  
  265. static struct tlentry *llookup(id)
  266. char *id;
  267.    {
  268.    register struct tlentry *ptr;
  269.  
  270.    ptr = lhash[lhasher(id)];
  271.    while (ptr != NULL && ptr->l_name != id)
  272.       ptr = ptr->l_blink;
  273.    return ptr;
  274.    }
  275.  
  276. /*
  277.  * glookup looks up id in global symbol table and returns pointer to
  278.  *  to it if found or NULL if not present.
  279.  */
  280. static struct tgentry *glookup(id)
  281. char *id;
  282.    {
  283.    register struct tgentry *ptr;
  284.  
  285.    ptr = ghash[ghasher(id)];
  286.    while (ptr != NULL && ptr->g_name != id) {
  287.       ptr = ptr->g_blink;
  288.       }
  289.    return ptr;
  290.    }
  291.  
  292. /*
  293.  * clookup looks up id in constant symbol table and returns pointer to
  294.  *  to it if found or NULL if not present.
  295.  */
  296. static struct tcentry *clookup(id,flag)
  297. char *id;
  298. int flag;
  299.    {
  300.    register struct tcentry *ptr;
  301.  
  302.    ptr = chash[chasher(id)];
  303.    while (ptr != NULL && (ptr->c_name != id ||